package com.ddwl.search.esrepository.impl;

import cn.hutool.core.util.StrUtil;
import com.ddwl.common.util.BeanConverUtils;
import com.ddwl.schema.bo.base.PageBo;
import com.ddwl.schema.bo.search.GoodsSearchBo;
import com.ddwl.schema.vo.base.PageVo;
import com.ddwl.schema.vo.search.EsItemVo;
import com.ddwl.search.esrepository.EsProductRepositoryAdvance;
import com.ddwl.search.esrepository.domain.EsItem;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class EsProductRepositoryImpl implements EsProductRepositoryAdvance {

    @Autowired
    private ElasticsearchOperations operations;

    @Override
    public PageVo<EsItemVo> search(PageBo<GoodsSearchBo> pageBo) {
        Pageable pageable = PageRequest.of(pageBo.getPage() - 1, pageBo.getPageSize());
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        //分页
        nativeSearchQueryBuilder.withPageable(pageable);
        //过滤
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.termQuery("itemStatus", "1"));
        if (StrUtil.isNotBlank(pageBo.getParam().getCategoryId())) {
            boolQueryBuilder.must(QueryBuilders.termQuery("categoryId", pageBo.getParam().getCategoryId()));
        }
        if (StrUtil.isNotBlank(pageBo.getParam().getShopId())) {
            boolQueryBuilder.must(QueryBuilders.termQuery("shopId.keyword", pageBo.getParam().getShopId()));
        }
        if (StrUtil.isNotBlank(pageBo.getParam().getItemType())) {
            boolQueryBuilder.must(QueryBuilders.termQuery("itemType", pageBo.getParam().getItemType()));
        }
        nativeSearchQueryBuilder.withFilter(boolQueryBuilder);
        if (StrUtil.isNotEmpty(pageBo.getParam().getKeyword())) {
            BoolQueryBuilder boolQueryBuilder1 = new BoolQueryBuilder();
            boolQueryBuilder1.must(QueryBuilders.multiMatchQuery(pageBo.getParam().getKeyword(), "barcode", "itemName", "keywords"));
            //   boolQueryBuilder1.must(QueryBuilders.matchQuery("keywords", pageBo.getParam().getKeyword()));
            boolQueryBuilder1.should(QueryBuilders.termQuery("attributeList", pageBo.getParam().getKeyword()));
            boolQueryBuilder1.should(QueryBuilders.termQuery("paramDetail", pageBo.getParam().getKeyword()));
            boolQueryBuilder1.should(QueryBuilders.termQuery("categoryName", pageBo.getParam().getKeyword()));
            boolQueryBuilder1.should(QueryBuilders.termQuery("categoryId", "20200608002").boost(0.4f));
            nativeSearchQueryBuilder.withQuery(boolQueryBuilder1);
        }
        if (StrUtil.isNotBlank(pageBo.getSort())) {
            if (pageBo.isAsc()) {
                nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort(pageBo.getSort()).order(SortOrder.ASC));
            } else {
                nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort(pageBo.getSort()).order(SortOrder.DESC));
            }
        } else {
            nativeSearchQueryBuilder.withSort(SortBuilders.scoreSort().order(SortOrder.DESC));
        }
        nativeSearchQueryBuilder.withPageable(pageable);
        NativeSearchQuery searchQuery = nativeSearchQueryBuilder.build();
        SearchHits<EsItem> searchHits = operations.search(searchQuery, EsItem.class);
        List<EsItemVo> items = new ArrayList<>();
        for (Iterator<SearchHit<EsItem>> iterator = searchHits.iterator(); iterator.hasNext(); ) {
            items.add(BeanConverUtils.convertBean(iterator.next().getContent(), EsItemVo.class));
        }
        return new PageVo<>(searchHits.getTotalHits(), pageBo.getPage(), pageBo.getPageSize(), items);
    }
}
